﻿
using CGXi_Sdk;

using HarfBuzzSharp;
using ImTools;
using LiveChartsCore;
using LiveChartsCore.Defaults;
using LiveChartsCore.Kernel.Sketches;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Painting;
using MathNet.Numerics.RootFinding;
using NPOI.SS.Formula.Functions;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using static ImTools.ImMap;
using static NPOI.POIFS.Crypt.CryptoFunctions;
using static SkiaSharp.HarfBuzz.SKShaper;

namespace JES.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private string _title = "Prism Application";
        private readonly IDialogService _dialog;
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }
        private const int MaxRequestDataLength = 512000;
        private int CurrentDeviceId
        {
            get { return GetSelectedDeviceId(); }
        }
        private double _currentLength;
        /// <summary>
        /// 当前长度
        /// </summary>
        public double CurrentLength
        {
            get { return _currentLength; }
            set { SetProperty(ref _currentLength, value); }
        }
        private bool _isVertical;
        /// <summary>
        /// 是否垂直
        /// </summary>
        public bool IsVertical
        {
            get { return _isVertical; }
            set { SetProperty(ref _isVertical, value); }
        }
        private readonly DeviceData[] _deviceData;


        private readonly Random _random = new();

        // We use the ObservableCollection class to let the chart know // mark
        // when a new item is added or removed from the chart. // mark
        public ObservableCollection<ISeries> Series4 { get; set; }
        public ObservableCollection<ObservablePoint> ObservableValues_4 { get; set; }
        public ObservableCollection<ObservablePoint> ObservableValues_4_1 { get; set; }


        public ObservableCollection<ISeries> Series5 { get; set; }
        public ObservableCollection<ObservablePoint> ObservableValues_5 { get; set; }
        public ObservableCollection<ObservablePoint> ObservableValues_5_1 { get; set; }

        public ObservableCollection<ISeries> Series6 { get; set; }
        public ObservableCollection<ObservablePoint> ObservableValues_6 { get; set; }
        public ObservableCollection<ObservablePoint> ObservableValues_6_1 { get; set; }
        public ObservableCollection<ObservablePoint> ObservableValues_6_2 { get; set; }
        public ObservableCollection<ObservablePoint> ObservableValues_6_3 { get; set; }


        private double _minVerticalLength;
        /// <summary>
        /// 最小垂直长度
        /// </summary>
        public double MinVerticalLength
        {
            get { return _minVerticalLength; }
            set { SetProperty(ref _minVerticalLength, value); }
        }


        private List<double> _maxLengthList;
        /// <summary>
        /// 最大值列表
        /// </summary>
        public List<double> MaxLengthList
        {
            get { return _maxLengthList; }
            set { SetProperty(ref _maxLengthList, value); }
        }
        private int _testCount;
        /// <summary>
        /// 实验次数
        /// </summary>
        public int TestCount
        {
            get { return _testCount; }
            set { SetProperty(ref _testCount, value); }
        }

        


        private string _min4;
        /// <summary>
        /// 4轴最小值
        /// </summary>
        public string Min4
        {
            get { return _min4; }
            set { SetProperty(ref _min4, value); }
        }
        private string _min5;
        /// <summary>
        /// 5轴最小值
        /// </summary>
        public string Min5
        {
            get { return _min5; }
            set { SetProperty(ref _min5, value); }
        }
        private string _max6;
        /// <summary>
        /// 6轴最大值
        /// </summary>
        public string Max6
        {
            get { return _max6; }
            set { SetProperty(ref _max6, value); }
        }


        // The ObservablePoints property is an ObservableCollection of ObservableValue // mark
        // it means that the chart is listening for changes in this collection // mark
        // and also for changes in the properties of each element in the collection // mark


        // We use the ObservableCollection class to let the chart know // mark
        // when a new item is added or removed from the chart. // mark
        public ObservableCollection<ISeries> PieSeries { get; set; }
        //public ObservableCollection<ObservableValue> PieObservableValues { get; set; }

        private bool Isopen;
        private RobotHelper robotHelper;

        private double[] start;
        public DelegateCommand OpenCommand { get; set; }
        public DelegateCommand<string> OpenPageCommand { get; set; }
        
        public DelegateCommand CloseCommand { get; set; }
        public DelegateCommand<string> VerticalCommand { get; set; }
        public DelegateCommand ClearCommand { get; set; }
        


        private CancellationTokenSource cts;

        private ManualResetEvent manualEvent = new ManualResetEvent(false);

        public MainWindowViewModel(IDialogService dialog)
        {
            _dialog = dialog;
            //基恩士链接
            Inti();
            #region 界面显示数组初始化
            MaxLengthList = new List<double>();
            ObservableValues_4 = [
         
       ];
            ObservableValues_4_1 = [

      ];
            Series4 = [
             new LineSeries<ObservablePoint>(ObservableValues_4),
                new LineSeries<ObservablePoint>(ObservableValues_4_1)
         ];
            ObservableValues_5 = [

];
            ObservableValues_5_1 = [

      ];
            Series5 = [
             new LineSeries<ObservablePoint>(ObservableValues_5),
                new LineSeries<ObservablePoint>(ObservableValues_5_1)
         ];
            ObservableValues_6 = [];
            ObservableValues_6_1 = [];
            ObservableValues_6_2 = [];
            ObservableValues_6_3 = [];
            Series6 = [
             new LineSeries<ObservablePoint>(ObservableValues_6),
                new LineSeries<ObservablePoint>(ObservableValues_6_1),
                new LineSeries<ObservablePoint>(ObservableValues_6_2),
                new LineSeries<ObservablePoint>(ObservableValues_6_3),
          
         ];



            //ObservableValues_6.Add(new ObservablePoint() { X = 50, Y = 60.2 });
            //ObservableValues_6.Add(new ObservablePoint() { X = 50.3, Y = 62.2 });
            //ObservableValues_6.Add(new ObservablePoint() { X = 50.6, Y = 67.2 });

            //ObservableValues_6_1.Add(new ObservablePoint() { X = 50.01, Y = 60.2 });
            //ObservableValues_6_1.Add(new ObservablePoint() { X = 50.02, Y = 60.25 });
            //ObservableValues_6_1.Add(new ObservablePoint() { X = 50.03, Y = 60.27 });


            PieSeries = [
               
            ];
            #endregion
            //InitPieChart();
            cts = new CancellationTokenSource();
            CancellationToken token = cts.Token;
            Task.Run(() =>
            {
                GetData();
            }, cts.Token);
            //Application.Current.Dispatcher.Invoke(() =>
            //{
              
            //    //Thread thread2 = new Thread(AutoData);
            //    //thread2.Start();

            //});

            //Thread thread2 = new Thread(AutoData);
            //thread2.Start();
            OpenCommand = new DelegateCommand(Open);
            OpenPageCommand = new DelegateCommand<string>(OpenPage);
            CloseCommand = new DelegateCommand(() => manualEvent.Reset());
            VerticalCommand = new DelegateCommand<string>((t) => {
                if (t != null)
                {

                    if (t == "1")
                    {
                        IsVertical = true;
                    }
                    else
                    {
                        IsVertical = false;
                    }
                }
                else {
                    IsVertical = false;
                }

               
            }
          
            );
            robotHelper = new RobotHelper();
            ClearCommand = new DelegateCommand(Clear);




        }
        public void OpenPage(string obj)
        {
            if (!string.IsNullOrEmpty(obj))
            {
                DialogParameters parameters = new DialogParameters();
                parameters.Add("type", obj);
                // 导航到 ContentRegion 中指定的视图
                _dialog.ShowDialog("LabList", parameters, null);

            }
        }

        /// <summary>
        /// 开始自动测量
        /// </summary>
        public void Open()
        {
            NPOLHelper npoi = new NPOLHelper();
            int count = 1;
            TestCount = 0;
            //开始读取长度
            manualEvent.Set();
            Thread thread = new Thread(() =>
            {
                int hold = 2;
                List<TestValue> values = new List<TestValue>(); 
                for(int i=0; i<count;i++)
                {
                    TestCount++;
                    TestValue value = new TestValue();
                    //回到原点 
                    robotHelper.ReturnOrigin();

                    //移动Z轴
                    ZMove(-40);

                    ////4轴1°
                    //SingleMove_V(3, 4, 0.5, true, ObservableValues_4, 10);
                    //////4轴0.1°
                    //var v4 = SingleMove_V(3, 5, 0.1, false, ObservableValues_4_1, 10);
                    //Min4 = v4.Length.ToString("f3") + ",角度:" + v4.Pose[3];


                    //6轴180
                    var v60 = DoubleMove_H(true, 10, 20, ObservableValues_6, 10);

                    //6轴1°
                    DoubleMove_H(false, 10, 2, ObservableValues_6_1, 10, true);
                    //6轴0.1°
                    var v6 = DoubleMove_H(false, 10, 0.2, ObservableValues_6_2, 10, false);

                    var v62 = DoubleMove_H(false, 10, 0.02, ObservableValues_6_3, 10, false);
                    Max6 = v62.Length.ToString("f3") + ",角度:" + v6.Pose[5];

                    //4轴1°
                    //SingleMove_V(3, 4, 0.5, true, ObservableValues_4,10);
                    ////4轴0.1°
                    //var v4= SingleMove_V(3, 5, 0.1, false, ObservableValues_4_1,10);
                    //Min4 = v4.Length.ToString("f3") + ",角度:" + v4.Pose[3];

                    //robotHelper.MovePos(5, -90);
                    ////5轴1°
                    //SingleMove_V(4, 4, 0.5, true, ObservableValues_5,10);
                    ////5轴0.1°
                    //var v5 = SingleMove_V(4, 5, 0.1, false, ObservableValues_5_1, 10);
                    //Min5 = v5.Length.ToString("f3") + ",角度:" + v5.Pose[4];
                    //6轴180
                    //SingleMove_H(true, 18, 10, true, ObservableValues_6,10);

                    ////6轴1°
                    //SingleMove_H(false, 10, 1, true, ObservableValues_6_1,10,true);
                    ////6轴0.1°
                    //var v6  = SingleMove_H(false, 10, 0.1, false, ObservableValues_6_2,10,true);






                    //移动第四轴取最小值
                    //PoseMove(3, value, hold);
                    //移动第五轴取最小值
                    //PoseMove(4, value, hold);
                    //移动第六轴取最小值
                    //PoseMove(5, value, hold);


                    //摆动RX轴获取最小值
                    //XYMove(2, value, hold);
                    //RXMove_Stop(2, value, hold);
                    //RXMove(2, value, hold);
                    //水平定位获取最大值
                    //XYMove(2, value, hold);

                    //List<double> maxlist = new List<double>();
                    //for(int i=0; i<10;i++)
                    //{
                    //    maxlist.Add(GetMax2());
                    //}
                    //values.Add(value);

                }
                npoi.Created(values, hold);






            });
            thread.Start();

        }

        /// <summary>
        /// 移动Z轴到基恩士设备能正常读值的位置
        /// </summary>
        /// <param name="step"></param>
        public void ZMove(int step)
        {
            CurrentLength = 0;
            //获取当前位置
            robotHelper.Movejog_tcp(2, step, 25);


            while (true)
            {
                //获取当前位置
                robotHelper.Movejog_tcp(2, step, 25);
                //如果已经进入轮对内部
                if (CurrentLength != 0)
                {
                    //一次性下降到检测部位并跳出循环
                    Thread.Sleep(100);
                    robotHelper.Movejog_tcp(2, -60, 25);
                    //此处定位为原点
                    start = [0, 0];
                    break;
                }

            }
        }

        #region 单激光信号

        /// <summary>
        /// 记录之前暂停一定时间
        /// </summary>
        /// <param name="time"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public double AvG_Length(int time,int count)
        {
            List<double> lengths=new List<double>();
            Thread.Sleep(2000);
            for (int i = 0; i < count; i++)
            {
                Thread.Sleep(time);
                lengths.Add(CurrentLength);
                
            }
            return lengths.Average();
        }


        /// <summary>
        /// 单激光信号移动(垂直)45轴
        /// </summary>
        /// <param name="index">移动的轴</param>
        /// <param name="move">移动的步数</param>
        /// <param name="corner">每次移动的角度</param>
        /// <param name="direction">正转反转</param>
        public PoseDetail SingleMove_V(int index,int move,double cor,bool direction, ObservableCollection<ObservablePoint> points,int count)
        {
            List<PoseDetail> length = new List<PoseDetail>();
            //上下移动 上
            for (int i = 0; i < move; i++)
            {
                robotHelper.MovePos(index, cor);
                

                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                    MoveCorner= i+1
                };
                length.Add(detail);
            
            }
            robotHelper.MovePos(index, -move*cor);
            //下
            for (int i = 0; i < move; i++)
            {
                robotHelper.MovePos(index, -cor);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                    MoveCorner = -i-1
                };
                length.Add(detail);

            }
            robotHelper.MovePos(index, move * cor);
            length.Add(new PoseDetail()
            {
                Length = AvG_Length(100,count),
                Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                MoveCorner = 0
            });
            //旋转
            robotHelper.MovePos(5, direction == true ? 170 : -170,40);
            robotHelper.MovePos(5, direction == true ? 10 : -10, 5);
            List<PoseDetail> length2 = new List<PoseDetail>();
            length2.Add(new PoseDetail()
            {
                Length = AvG_Length(100,count),
                Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                MoveCorner = 0
            });
       
            //上下移动 上
            for (int i = 0; i < move; i++)
            {
                robotHelper.MovePos(index, cor);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                    MoveCorner = -i - 1
                };
                length2.Add(detail);

            }
            robotHelper.MovePos(index, -move * cor);
            //下
            for (int i = 0; i < move; i++)
            {
                robotHelper.MovePos(index, -cor);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                    MoveCorner = i + 1
                };
                length2.Add(detail);

            }
            //robotHelper.MovePos(index, move * cor);
            //合计
            List<PoseDetail> length3 = new List<PoseDetail>();
            length2.ForEach(p => {
                //获取对应值
               var corner= length.FirstOrDefault(t => t.MoveCorner == p.MoveCorner * -1);
                var pose = new PoseDetail()
                {
                    Length = p.Length + corner.Length,
                    Pose = p.Pose
                };
                length3.Add(pose);
                points.Add(new ObservablePoint() { X = p.Pose[index], Y = pose.Length });
            });
            
            //找到最小值
            
            var min= length3.First(t => t.Length == length3.Min(f => f.Length));

            //移动到最小位置
            robotHelper.MovePos(index, min.Pose[index],25,true);

            return min;

        }

        /// <summary>
        /// 单激光信号移动(水平)6轴
        /// </summary>
        /// <param name="all">是否转一圈</param>
        /// <param name="move">移动的步数</param>
        /// <param name="corner">每次移动的角度</param>
        /// <param name="direction">正转反转</param>
        public PoseDetail SingleMove_H(bool all, int move, double cor, bool direction, ObservableCollection<ObservablePoint> points,int count, bool use1=false)
        {
            double count0 = 0;
            int index = 5;
            if(all)
            {
                List<PoseDetail> length = new List<PoseDetail>();
                length.Add(new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                    MoveCorner = 0
                });
                //上下移动 上
                for (int i = 1; i < move; i++)
                {
                    robotHelper.MovePos(index, cor,20);
                    PoseDetail detail = new PoseDetail()
                    {
                        Length = AvG_Length(100,count),
                        Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                        MoveCorner = i
                    };
                    length.Add(detail);
                }
             
                robotHelper.MovePos(index, -340, 40);
                robotHelper.MovePos(index, -10, 5);
             
                //下
                List<PoseDetail> length2 = new List<PoseDetail>();
                length2.Add(new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                    MoveCorner = -18
                });
                for (int i = 1; i < move; i++)
                {
                    robotHelper.MovePos(index, cor,20);
                    PoseDetail detail = new PoseDetail()
                    {
                        Length = AvG_Length(100,count),
                        Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                        MoveCorner = -18+i
                    };
                    length2.Add(detail);
                }
                //对称的角度相加
                List<PoseDetail> length3 = new List<PoseDetail>();
                length2.ForEach(p => {
                    //获取对应值
                    var corner = length.FirstOrDefault(t =>Math.Abs(t.MoveCorner)+Math.Abs(p.MoveCorner)==18 );
                    length3.Add(new PoseDetail()
                    {
                        Length = p.Length + corner.Length,
                        Pose = p.Pose
                    });
                    points.Add(new ObservablePoint() { X = p.Pose[index], Y = p.Length + corner.Length });
                });
                


                //找到最大值
                var max = length3.First(t => t.Length == length3.Max(f => f.Length));
                //移动到最大位置
                robotHelper.MovePos(index, max.Pose[index],5,true);
                return max;
            }
            else
            {
                List<PoseDetail> length = new List<PoseDetail>();
                //上下移动 上
                for (int i = 0; i < move; i++)
                {
                    robotHelper.MovePos(index, cor);
                    PoseDetail detail = new PoseDetail()
                    {
                        Length = AvG_Length(100,count),
                        Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                        MoveCorner = i + 1
                    };
                    length.Add(detail);

                }
                robotHelper.MovePos(index, -move * cor);
                //下
                for (int i = 0; i < move; i++)
                {
                    robotHelper.MovePos(index, -cor);
                    PoseDetail detail = new PoseDetail()
                    {
                        Length = AvG_Length(100,count),
                        Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                        MoveCorner = -i - 1
                    };
                    length.Add(detail);

                }
                robotHelper.MovePos(index, move * cor);
                length.Add(new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                    MoveCorner = 0
                });
                //旋转
                robotHelper.MovePos(5, robotHelper.api_demo_cr_get_jointActualPos()[5]<-180?170 : -170, 40);
                robotHelper.MovePos(5, robotHelper.api_demo_cr_get_jointActualPos()[5] < -180 ? 10 : -10, 5);
                List<PoseDetail> length2 = new List<PoseDetail>();
                length2.Add(new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                    MoveCorner = 0
                });

                //上下移动 上
                for (int i = 0; i < move; i++)
                {
                    robotHelper.MovePos(index, cor);
                    PoseDetail detail = new PoseDetail()
                    {
                        Length = AvG_Length(100,count),
                        Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                        MoveCorner = -i - 1
                    };
                    length2.Add(detail);

                }
                robotHelper.MovePos(index, -move * cor);
                //下
                for (int i = 0; i < move; i++)
                {
                    robotHelper.MovePos(index, -cor);
                    PoseDetail detail = new PoseDetail()
                    {
                        Length = AvG_Length(100,count),
                        Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                        MoveCorner = i + 1
                    };
                    length2.Add(detail);

                }
                //robotHelper.MovePos(index, move * cor);
                //合计
                List<PoseDetail> length3 = new List<PoseDetail>();
               
                if (use1)
                {
                    length.ForEach(p => {
                        //获取对应值
                        var corner = length2.FirstOrDefault(t => t.MoveCorner == p.MoveCorner * -1);
                        var pose = new PoseDetail()
                        {
                            Length = p.Length + corner.Length,
                            Pose = p.Pose
                        };
                        length3.Add(pose);
                        points.Add(new ObservablePoint() { X = p.Pose[index], Y = pose.Length });
                    });
                }
                else
                {
                    length2.ForEach(p => {
                        //获取对应值
                        var corner = length.FirstOrDefault(t => t.MoveCorner == p.MoveCorner * -1);
                        var pose = new PoseDetail()
                        {
                            Length = p.Length + corner.Length,
                            Pose = p.Pose
                        };
                        length3.Add(pose);
                        points.Add(new ObservablePoint() { X = p.Pose[index], Y = pose.Length });
                    });
                }
              
                //找到最大
                var max = length3.First(t => t.Length == length3.Max(f => f.Length));
                //移动到最大位置
                robotHelper.MovePos(index, max.Pose[index],5,true);

                return max;
                
            }

           
        }

        #endregion
        #region 双激光激光信号  姿态一动

        /// <summary>
        /// 双激光信号移动(垂直)45轴
        /// </summary>
        /// <param name="index">移动的轴</param>
        /// <param name="move">移动的步数</param>
        /// <param name="corner">每次移动的角度</param>
        /// <param name="direction">正转反转</param>
        public PoseDetail DoubleMove_V(int index, int move, double cor, bool direction, ObservableCollection<ObservablePoint> points, int count)
        {
            List<PoseDetail> length = new List<PoseDetail>();
            //上下移动 上
            for (int i = 0; i < move; i++)
            {
                robotHelper.MovePos(index, cor);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100, count),
                    Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                    MoveCorner = i + 1
                };
                length.Add(detail);

            }
            robotHelper.MovePos(index, -move * cor);
            //下
            for (int i = 0; i < move; i++)
            {
                robotHelper.MovePos(index, -cor);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100, count),
                    Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                    MoveCorner = -i - 1
                };
                length.Add(detail);

            }
            robotHelper.MovePos(index, move * cor);
            length.Add(new PoseDetail()
            {
                Length = AvG_Length(100, count),
                Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                MoveCorner = 0
            });
           
            //找到最小值

            var min = length.First(t => t.Length == length.Min(f => f.Length));

            //移动到最小位置
            robotHelper.MovePos(index, min.Pose[index], 25, true);

            return min;

        }

        /// <summary>
        /// 双激光信号移动(水平)6轴
        /// </summary>
        /// <param name="all">是否转一圈</param>
        /// <param name="move">移动的步数</param>
        /// <param name="points">图像集合</param>
        /// <param name="count">正转反转</param>
        /// <param name="count">统计平均值个数</param>
        /// <param name="isAvg">是否需要平均</param>
        public PoseDetail DoubleMove_H(bool all, int move, double cor, ObservableCollection<ObservablePoint> points, int count, bool isAvg = false)
        {
            double count0 = 0;
            int index = 5;
            if (all)
            {
                List<PoseDetail> length = new List<PoseDetail>();
                var deail1 = new PoseDetail()
                {
                    Length = AvG_Length(100, count),
                    Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                    MoveCorner = 0
                };
                length.Add(deail1);
                points.Add(new ObservablePoint() { X = deail1.Pose[index], Y = deail1.Length });
                //上下移动 上
                for (int i = 1; i < move; i++)
                {
                    robotHelper.MovePos(index, cor, 20);
                    PoseDetail detail = new PoseDetail()
                    {
                        Length = AvG_Length(100, count),
                        Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                        MoveCorner = i
                    };
                    length.Add(detail);
                    points.Add(new ObservablePoint() { X = detail.Pose[index], Y = detail.Length });
                }
                //找到最大值
                var max = length.First(t => t.Length == length.Max(f => f.Length));
                //移动到最大位置
                robotHelper.MovePos(index, max.Pose[index], 25, true);
                return max;
            }
            else
            {
                List<PoseDetail> length = new List<PoseDetail>();
                //上下移动 上
                for (int i = 0; i < move; i++)
                {
                    robotHelper.MovePos(index, cor);
                    PoseDetail detail = new PoseDetail()
                    {
                        Length = AvG_Length(100, count),
                        Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                        MoveCorner = i + 1
                    };
                    length.Add(detail);
                    points.Add(new ObservablePoint() { X = detail.Pose[index], Y = detail.Length });

                }
                robotHelper.MovePos(index, -move * cor);
                //下
                for (int i = 0; i < move; i++)
                {
                    robotHelper.MovePos(index, -cor);
                    PoseDetail detail = new PoseDetail()
                    {
                        Length = AvG_Length(100, count),
                        Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                        MoveCorner = -i - 1
                    };
                    length.Add(detail);
                    points.Add(new ObservablePoint() { X = detail.Pose[index], Y = detail.Length });
                }
                robotHelper.MovePos(index, move * cor);
                var deail1 = new PoseDetail()
                {
                    Length = AvG_Length(100, count),
                    Pose = robotHelper.api_demo_cr_get_jointActualPos(),
                    MoveCorner = 0
                };
                length.Add(deail1);
                points.Add(new ObservablePoint() { X = deail1.Pose[index], Y = deail1.Length });
                //找到最大
                //List<PoseDetail> avgList = new List<PoseDetail>();
                //if(isAvg)
                //{
                //    for (int i = 0; i < length.Count; i++)
                //    {
                //        double avg1 = 0;
                //        if (i > 0)
                //        {
                //            avg1 = length[i - 1].Length;
                //        }
                //        else
                //        {
                //            avg1 = length[i].Length;
                //        }
                //        double avg2 = 0;
                //        if (i < length.Count - 1)
                //        {
                //            avg2 = length[i + 1].Length;
                //        }
                //        else
                //        {
                //            avg2 = length[i].Length;
                //        }


                //        double avg_max = (avg1 + avg2 + length[i].Length) / 3;
                //        avgList.Add(new PoseDetail() { Length = avg_max, Pose = length[i].Pose });
                //    }
                //}
            

                //var max =isAvg? avgList.First(t => t.Length == avgList.Max(f => f.Length)) : length.First(t => t.Length == length.Max(f => f.Length));
                var max = length.First(t => t.Length == length.Max(f => f.Length));

                //移动到最大位置
                robotHelper.MovePos(index, max.Pose[index], 25, true);

                //齿轮回差消除
                //if(!isAvg)
                //{
                //    double count1 = 20;
                //    double count2 = 3;

                //    List<double> doubles = new List<double>();
                //    for (int i = 1; i < count2; i++)
                //    {
                //        robotHelper.MovePos(index, max.Pose[index] + count1 * i, 25, true);
                //        robotHelper.MovePos(index, max.Pose[index], 25, true);
                //        var return1 = AvG_Length(100, count);
                //        robotHelper.MovePos(index, max.Pose[index] - count1 * i, 25, true);
                //        robotHelper.MovePos(index, max.Pose[index], 25, true);
                //        var return2 = AvG_Length(100, count);

                //        doubles.Add((return1 + return2) / 2);

                //    }
                //    max.Length = doubles.Average();

                //}



                
                return max;

            }


        }

        #endregion

        #region 双激光信号
        /// <summary>
        /// 机械臂轴运动
        /// </summary>
        /// <param name="index">要运动的轴</param>
        public PoseDetail PoseMove(int index, TestValue value, double hold,int count=10)
        {
            //第五轴运动，第六轴要先转90°
            if(index==4)
            {
                robotHelper.MovePos(5, -90);
            }

            List<PoseDetail> length = new List<PoseDetail>();
            //大范围扫描 获取最大值
            int move =index==5?180: 3;
            for (int i = 0; i < move; i++)
            {
                robotHelper.MovePos(index, 1);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_jointActualPos()
                };
                length.Add(detail);
            }
            if(index!=5)
            {
                robotHelper.MovePos(index, -move);
                for (int i = 0; i < move; i++)
                {
                    robotHelper.MovePos(index, -1);
                    PoseDetail detail = new PoseDetail()
                    {
                        Length = AvG_Length(100,count),
                        Pose = robotHelper.api_demo_cr_get_tcpActualPose()
                    };
                    length.Add(detail);
                }

            }

            //获取最大值或最小值位置
            var max_Length = length.First(t => t.Length ==(index == 5 ? length.Max(f => f.Length) : length.Min(f => f.Length)));
            //移动到最大值位置
            robotHelper.MoveToPos(max_Length.Pose);


            //中范围扫描 获取最大值
       
            for (int i = 0; i < 10; i++)
            {
                robotHelper.MovePos(index, 0.1);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_jointActualPos()
                };
                length.Add(detail);
            }
            robotHelper.MovePos(index, -10*0.1);
            for (int i = 0; i < 10; i++)
            {
                robotHelper.MovePos(index, -0.1);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_tcpActualPose()
                };
                length.Add(detail);
            }

            //获取最大值或最小值位置
            var max_Length2 = length.First(t => t.Length == (index == 5 ? length.Max(f => f.Length) : length.Min(f => f.Length)));
            //移动到最大值位置
            robotHelper.MoveToPos(max_Length.Pose);

            var t = CurrentLength;

            value.Pos_Max = new PosKeyValue() { PosIndex=index, Pos= max_Length.Pose ,Value=t };



            PoseDetail poseDetail = new PoseDetail() { Length = CurrentLength };
            return poseDetail;
        }

        /// <summary>
        /// 水平方向移动到最大值
        /// </summary>
        /// <param name="step">步进</param>
        public PoseDetail XYMove(int step,TestValue value,double hold, int count = 10)
        {

            List<PoseDetail> length = new List<PoseDetail>();
            //大范围扫描 获取最大值
            int move = 10;
            for (int i = 0; i < 10; i++)
            {
                robotHelper.Movejog_tcp(0, 1);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_tcpActualPose()
                };
                length.Add(detail);
            }
            robotHelper.Movejog_tcp(0, -move);
            for (int i = 0; i < 10; i++)
            {
                robotHelper.Movejog_tcp(0, -1);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_tcpActualPose()
                };
                length.Add(detail);
            }
            //robotHelper.Movejog_tcp(0, move);
            //获取最大值位置
            var max_Length = length.First(t => t.Length == length.Max(f => f.Length));
            //移动到最大值位置
            robotHelper.Movejog_tcp(0, max_Length.Pose[0]- robotHelper.api_demo_cr_get_tcpActualPose()[0]);


            //中范围扫描 获取最大值
         
            for (int i = 0; i < 10; i++)
            {
                robotHelper.Movejog_tcp(0, 0.1);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_tcpActualPose()
                };
                length.Add(detail);
            }
            robotHelper.Movejog_tcp(0, -move*0.1);
            for (int i = 0; i < 10; i++)
            {
                robotHelper.Movejog_tcp(0, -0.1);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_tcpActualPose()
                };
                length.Add(detail);
            }
            //robotHelper.Movejog_tcp(0, move* 0.1);
            //获取最大值位置
            var max_Length2 = length.First(t => t.Length == length.Max(f => f.Length));
            //移动到最大值位置
            robotHelper.Movejog_tcp(0, max_Length2.Pose[0] - robotHelper.api_demo_cr_get_tcpActualPose()[0]);



            //小范围扫描 获取最大值

            for (int i = 0; i < 10; i++)
            {
                robotHelper.Movejog_tcp(0, 0.01);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_tcpActualPose()
                };
                length.Add(detail);
            }
            robotHelper.Movejog_tcp(0, -move * 0.01);
            for (int i = 0; i < 10; i++)
            {
                robotHelper.Movejog_tcp(0, -0.01);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_tcpActualPose()
                };
                length.Add(detail);
            }
            //robotHelper.Movejog_tcp(0, move * 0.01);
            //获取最大值位置
            var max_Length3 = length.First(t => t.Length == length.Max(f => f.Length));
            //移动到最大值位置
            robotHelper.Movejog_tcp(0, max_Length3.Pose[0] - robotHelper.api_demo_cr_get_tcpActualPose()[0]);

            var t = CurrentLength;

            value.AC_Max = t;




            //var v1 = CurrentLength;
            //robotHelper.Movejog_tcp(0, 0.01);
            //var v2 = CurrentLength;
            //robotHelper.Movejog_tcp(0, 0.01);
            //var v3 = CurrentLength;

            ////变大
            //if (CurrentLength > ori_max)
            //{
            //    ori_max = CurrentLength;
            //    while (true)
            //    {
            //        robotHelper.Movejog_tcp(0, 0.01);
            //        if (CurrentLength > ori_max)
            //        {
            //            ori_max = CurrentLength;
            //        }
            //        else
            //        {
            //            robotHelper.Movejog_tcp(0, -0.01);
            //            break;
            //        }
            //    }
            //}
            //else
            //{
            //    robotHelper.Movejog_tcp(0, -0.01);
            //    ori_max = CurrentLength;
            //}



            ////误差在允许范围之内
            //if (max_Length.Length - CurrentLength <= 0.015)
            //{

            //}
            //else//误差之外  尝试逼近最大值
            //{
            //    var ori_max =CurrentLength ;
            //    //正方向移动
            //    robotHelper.Movejog_tcp(0, 0.01);
            //    //变大
            //    if(CurrentLength> ori_max)
            //    {
            //        ori_max = CurrentLength;
            //        while (true)
            //        {
            //            robotHelper.Movejog_tcp(0, 0.01);
            //            if(CurrentLength > ori_max)
            //            {
            //                ori_max = CurrentLength;
            //            }
            //            else
            //            {
            //                robotHelper.Movejog_tcp(0, -0.01);
            //                break;
            //            }
            //        }
            //    }
            //    else
            //    {
            //        robotHelper.Movejog_tcp(0, -0.01);
            //        ori_max = CurrentLength;
            //    }


            //}


            //int take_num = 5;
            //var order = length.OrderByDescending(t => t.Length).Take(take_num);
            //value.AC_Max = order.Max(t => t.Length);
            //double avg = order.Sum(t=>t.Length) / take_num;
            //value.AVG_Max= avg;
            //double avg_pose = order.Sum(t => t.Pose[0]) / take_num;
            //var cur_pose = robotHelper.api_demo_cr_get_tcpActualPose()[0];
            //var max_pose = order.First(t=>t.Length== order.Max(f=>f.Length)).Pose[0] ;
            //double move_length = max_pose - cur_pose;
            ////double move_length = avg_pose - cur_pose;
            //robotHelper.Movejog_tcp(0, move_length);
            //value.Return_Max = CurrentLength;
            //var ori= robotHelper.api_demo_cr_get_tcpActualPose();
            ////和平均值做比较
            //var avg_numer = avg - CurrentLength;
            ////标准为0.015
            //if (avg_numer >0.015)
            //{
            //    //尝试逼进 连续两次
            //    robotHelper.Movejog_tcp(0, 0.01);
            //    var now1 = avg - CurrentLength;
            //    robotHelper.Movejog_tcp(0, 0.01);
            //    var now2 = avg - CurrentLength;
            //    robotHelper.Movejog_tcp(0, 0.01);
            //    var now3 = avg - CurrentLength;
            //    //变的更远则返回一步
            //    if (now3 > now2&&now2 > now1)
            //    {
            //        robotHelper.Movejog_tcp(0, -0.02);
            //        value.AC_Max = CurrentLength;
            //    }
            //    //没有超过平均值
            //   else if (now3 < now2 && now3 < now1)
            //    {
            //        var number3 = avg - CurrentLength;
            //        while (true)
            //        {
            //            //根据大小值判断运行方向
            //            robotHelper.Movejog_tcp(0, 0.01);
            //            //如果这个值已和平均值相吻合，则尝试吻合最大值
            //            if (CurrentLength - avg < number3)
            //            {
            //                number3 = avg- CurrentLength ;
            //            }
            //            else
            //            {
            //                //返回一步
            //                robotHelper.Movejog_tcp(0, - 0.01);
            //                break;
            //            }
            //            if (number3<0.015)
            //            {
            //                var number4 = CurrentLength- avg ;
            //                while (true)
            //                {
            //                    robotHelper.Movejog_tcp(0, now2 < now1 ? 0.01 : -0.01);
            //                    if(CurrentLength-avg>number4)
            //                    {
            //                        number4 = CurrentLength - avg;
            //                    }
            //                    else
            //                    {
            //                        //返回一步
            //                        robotHelper.Movejog_tcp(0, now2 < now1 ? -0.01 : 0.01);
            //                        break;
            //                    }

            //                }
            //            }
            //        }
            //    }
            //}
            //else if(avg_numer<0.015)
            //{
            //    //尝试逼进 连续两次
            //    robotHelper.Movejog_tcp(0, 0.01);
            //    var now1 = value.AC_Max - CurrentLength;
            //    robotHelper.Movejog_tcp(0, 0.01);
            //    var now2 = value.AC_Max - CurrentLength;
            //    robotHelper.Movejog_tcp(0, -0.01);
            //}


            PoseDetail poseDetail = new PoseDetail() { Length = CurrentLength };
            return poseDetail;
        }

        /// <summary>
        /// 水平方向移动到最大值 静止测试
        /// </summary>
        /// <param name="step">步进</param>
        public PoseDetail XYMove_Stop(int step, TestValue value, double hold, int count = 10)
        {
            //控制循环
            bool cycle = true;
            List<PoseDetail> length = new List<PoseDetail>();
            //持续记录当前位置和长度
            Thread thread = new Thread(() =>
            {
                while (cycle)
                {
                    PoseDetail detail = new PoseDetail()
                    {
                        Length = AvG_Length(100,count),
                        Pose = robotHelper.api_demo_cr_get_tcpActualPose()
                    };
                    length.Add(detail);
                    Thread.Sleep(100);
                }
            });
          
            int move = 10;
            thread.Start();
            start[0] += move;
            robotHelper.Movejog_tcp(0, move);
            start[0] += -2 * move;
            robotHelper.Movejog_tcp(0, -2 * move);
            start[0] += move;
            robotHelper.Movejog_tcp(0, move);
            //start[0] += move;
            //for (int i = 0; i < move / 0.1; i++)
            //{
            //    robotHelper.Movejog_tcp(0, 0.1, 0.5);
            //    PoseDetail detail = new PoseDetail()
            //    {
            //        Length = AvG_Length(100,count),
            //        Pose = robotHelper.api_demo_cr_get_tcpActualPose()
            //    };
            //    length.Add(detail);
            //}
       
            //start[0] += -2 * move;
            //for (int i = 0; i < 2 * move / 0.1; i++)
            //{
            //    robotHelper.Movejog_tcp(0, -0.1, 0.5);
            //    PoseDetail detail = new PoseDetail()
            //    {
            //        Length = AvG_Length(100,count),
            //        Pose = robotHelper.api_demo_cr_get_tcpActualPose()
            //    };
            //    length.Add(detail);
            //}
       
            //start[0] += move;
            //for (int i = 0; i < move / 0.1; i++)
            //{
            //    robotHelper.Movejog_tcp(0, 0.1, 0.5);
            //    PoseDetail detail = new PoseDetail()
            //    {
            //        Length = AvG_Length(100,count),
            //        Pose = robotHelper.api_demo_cr_get_tcpActualPose()
            //    };
            //    length.Add(detail);
            //}
            cycle = false;
            //数据筛选
            int take_num = 5;
            length = FilterByRateOfChange(length, hold);
            var order = length.OrderByDescending(t => t.Length).Take(take_num);
            value.AC_Max = order.Max(t => t.Length);
            double max = order.Sum(t => t.Length) / take_num;
            value.AVG_Max = value.AC_Max;
            double avg_pose = order.Sum(t => t.Pose[0]) / take_num;
            var cur_pose = robotHelper.api_demo_cr_get_tcpActualPose()[0];
            double move_length = avg_pose - cur_pose;
            robotHelper.Movejog_tcp(0, move_length);
            PoseDetail poseDetail = new PoseDetail() { Length = max };
            return poseDetail;
        }

        /// <summary>
        /// 摆动R轴获取最小值
        /// </summary>
        /// <param name="step">步进</param>
        public PoseDetail RXMove(int step, TestValue value, double hold, int count = 10)
        {
            //控制循环
            bool cycle = true;
            List<PoseDetail> length = new List<PoseDetail>();
            //持续记录当前位置和长度
            Thread thread = new Thread(() =>
            {
                while (cycle)
                {
                    PoseDetail detail = new PoseDetail()
                    {
                        Length = AvG_Length(100,count),
                        Pose = robotHelper.api_demo_cr_get_tcpActualPose()
                    };
                    length.Add(detail);
                    Thread.Sleep(100);
                }
            });
            thread.Start();
            //start[1] += 2;
            robotHelper.Movejog_tcp(3, 2,0.2);
            //start[1] += -4;
            robotHelper.Movejog_tcp(3, -4, 0.2);
            //start[1] += 2;
            robotHelper.Movejog_tcp(3, 2, 0.2);
            cycle = false;
            //数据筛选
            length = FilterByRateOfChange(length, hold);
            var order = length.OrderBy(t => t.Length).Take(10).ToList();
            value.AC_Min = length.Min(t => t.Length);
            double min = order.Sum(t => t.Length) / 10;
            value.AVG_Min = min;
            double avg_pose = order.Sum(t => t.Pose[3]) / 10;
            var cur_pose = robotHelper.api_demo_cr_get_tcpActualPose()[3];
            double move_length = order[0].Pose[3] - cur_pose;
            //double move_length = avg_pose - cur_pose;
            robotHelper.Movejog_tcp(3, move_length, 0.1);

            PoseDetail poseDetail = new PoseDetail() { Length = min };
            return poseDetail;
        }

        /// <summary>
        /// 摆动R轴获取最小值 静止测量
        /// </summary>
        /// <param name="step">步进</param>
        public PoseDetail RXMove_Stop(int step, TestValue value, double hold, int count = 10)
        {

            List<PoseDetail> length = new List<PoseDetail>();
  
            double move = 2;

            for(int i=0;i<move/0.1;i++)
            {
                robotHelper.Movejog_tcp(3, 0.1, 0.5);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_tcpActualPose()
                };
                length.Add(detail);
            }
            for (int i = 0; i <2 *move / 0.1; i++)
            {
                robotHelper.Movejog_tcp(3, -0.1, 0.5);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_tcpActualPose()
                };
                length.Add(detail);
            }
            for (int i = 0; i < move / 0.1; i++)
            {
                robotHelper.Movejog_tcp(3, 0.1, 0.5);
                PoseDetail detail = new PoseDetail()
                {
                    Length = AvG_Length(100,count),
                    Pose = robotHelper.api_demo_cr_get_tcpActualPose()
                };
                length.Add(detail);
            }



     
        
            //数据筛选
            length = FilterByRateOfChange(length, hold);
            var order = length.OrderBy(t => t.Length).Take(10).ToList();
            value.AC_Min = length.Min(t => t.Length);
            double min = order.Sum(t => t.Length) / 10;
            value.AVG_Min = min;
            double avg_pose = order.Sum(t => t.Pose[3]) / 10;
            var cur_pose = robotHelper.api_demo_cr_get_tcpActualPose()[3];
            double move_length = order[0].Pose[3] - cur_pose;
            //double move_length = avg_pose - cur_pose;
            robotHelper.Movejog_tcp(3, move_length, 0.1);

            PoseDetail poseDetail = new PoseDetail() { Length = min };
            return poseDetail;
        }


        /// <summary>
        /// 移动到边界值 最大最小值
        /// </summary>
        /// <param name="step">步进距离</param>
        /// <param name="axis">xyz 012 最大值  rxryrz 345 最小值</param>
        public void MoveToBoundary(int step, int axis)
        {
            List<PoseDetail> poses = new List<PoseDetail>();
            double value = 0;
            //获取开始长度
            var o_length = CurrentLength;
            //移动正方向
            for(int i=0;i<5;i++)
            {
                robotHelper.Movejog_tcp(axis, step);
                value += step;
                poses.Add(new PoseDetail() { SpotLength = value, Length = CurrentLength });
            }
        
            //xyz取最大值
            if (axis==0|| axis == 1|| axis == 2)
            {
                //运动后变小表示走反 往反方向走
                if (CurrentLength < o_length)
                    step = -step;
                var maxpose = new PoseDetail();
                int mincount = 0;
                //循环运动 并记录点位
                while (true)
                {
                    robotHelper.Movejog_tcp(axis, step);
                    value += step;
                    var pose = new PoseDetail() { SpotLength = value, Length = CurrentLength };
                    poses.Add(pose);
                    //不停的替换最大值
                    if(CurrentLength>maxpose.Length)
                    {
                        maxpose = pose;
                        mincount = 0;
                    }
                    //有可能是测量波动
                    if (CurrentLength < maxpose.Length)
                    {
                       
                        mincount += 1;
                        if(mincount==3)
                        {
                            continue;
                        }
                    }



                }

            }
        }
        #endregion 

        //public double GetMax()
        //{
        //    List<PoseDetail> poses = new List<PoseDetail>();
        //    double value = 0;
        //    int count = 200;
        //    //获取开始长度
        //    var o_length = CurrentLength;
        //    //移动正方向
        //    for (int i = 0; i < count; i++)
        //    {
        //        robotHelper.movejog_tcp(1,0.05);
        //        poses.Add(new PoseDetail() { SpotLength = value, Length = CurrentLength });
        //    }
        //    robotHelper.movejog_tcp(1, -0.05* count);
        //    for (int i = 0; i < count; i++)
        //    {
        //        robotHelper.movejog_tcp(1, -0.05);
        //        poses.Add(new PoseDetail() { SpotLength = value, Length = CurrentLength });
        //    }
        //    robotHelper.movejog_tcp(1, 0.05 * count);
        //    var order = poses.OrderBy(t => t.Length).Take(5);
        //    double max = order.Sum(t => t.Length) / 5;
        //    //double max = poses.Max(t => t.Length);
        //    return max;
        //}

        public double GetMax2()
        {

            //控制循环
            bool cycle = true;
            List<double> length = new List<double>();
            Thread thread = new Thread(() =>
            {
                while (cycle)
                {
                    length.Add(CurrentLength);
                    Thread.Sleep(10);
                }
            });
            thread.Start();
            robotHelper.Movejog_tcp(1, 10);
            robotHelper.Movejog_tcp(1, -20);
            robotHelper.Movejog_tcp(1, 10);
            cycle = false;
            var order = length.OrderBy(t => t).Take(5);
            double max = order.Sum() / 5;
            return max;
        }


        private void Clear()
        {
            manualEvent.Reset();
            CurrentLength = 0;
            //ObservableValues.Clear();
     
            MinVerticalLength = 0;
        }

        /// <summary>
        /// 基恩士连接
        /// </summary>
        public void Inti()
        {
            //进行连接
            int returnCode = NativeMethods.CL3IF_OpenUsbCommunication(0, 5000);
            //选择USB模式
            //SetDeviceStatement(returnCode, DeviceStatus.Usb);
        }
        private void SetDeviceStatement(int returnCode, DeviceStatus status)
        {
            if (returnCode == NativeMethods.CL3IF_RC_OK)
            {
                _deviceData[CurrentDeviceId].Status = status;
            }
            else
            {
                _deviceData[CurrentDeviceId].Status = DeviceStatus.NoConnection;
            }
        }

        public void GetData()
        {
            while(true)
            {
                //manualEvent.WaitOne();

                byte[] buffer = new byte[MaxRequestDataLength];
                using (PinnedObject pin = new PinnedObject(buffer))
                {
                    CL3IF_MEASUREMENT_DATA measurementData = new CL3IF_MEASUREMENT_DATA();
                    measurementData.outMeasurementData = new CL3IF_OUTMEASUREMENT_DATA[NativeMethods.CL3IF_MAX_OUT_COUNT];

                    int returnCode = NativeMethods.CL3IF_GetMeasurementData(CurrentDeviceId, pin.Pointer);
                    if (returnCode != NativeMethods.CL3IF_RC_OK)
                    {
                        //OutputLogMessage("GetMeasurementData", returnCode);
                        return;
                    }

                    measurementData.addInfo = (CL3IF_ADD_INFO)Marshal.PtrToStructure(pin.Pointer, typeof(CL3IF_ADD_INFO));
                    int readPosition = Marshal.SizeOf(typeof(CL3IF_ADD_INFO));
                    for (int i = 0; i < NativeMethods.CL3IF_MAX_OUT_COUNT; i++)
                    {
                        measurementData.outMeasurementData[i] = (CL3IF_OUTMEASUREMENT_DATA)Marshal.PtrToStructure(pin.Pointer + readPosition, typeof(CL3IF_OUTMEASUREMENT_DATA));
                        readPosition += Marshal.SizeOf(typeof(CL3IF_OUTMEASUREMENT_DATA));
                    }
                    var d1 = measurementData.outMeasurementData[0].measurementValue;
                    var d2 = measurementData.outMeasurementData[1].measurementValue;
                    var d3 = measurementData.outMeasurementData[2].measurementValue;
                    //var addNumber = 87.94255;
                    var addNumber = 0;
                    //if (d1>=0&&d2>=0)
                    //{
                    //    string data = (Convert.ToDouble(d1+d2) / 10000+ addNumber).ToString("f3");
                    //    Application.Current.Dispatcher.Invoke(() =>
                    //    {
                    //        CurrentLength = Convert.ToDouble(data);
                    //    });
                      
                    //    AutoData();
                    //}
                    if (d3>0)
                    {
                        string data = (Convert.ToDouble(d3) / 1000 + addNumber).ToString("f3");
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            CurrentLength = Convert.ToDouble(data);
                        });

                        AutoData();
                    }

                    Thread.Sleep(50);


                }
            }

        }

        private int GetSelectedDeviceId()
        {
            //foreach (Control control in _pnlDeviceId.Controls)
            //{
            //    RadioButton radioButton = control as RadioButton;
            //    if ((radioButton == null) || (!radioButton.Checked)) continue;

            //    return Convert.ToInt32(radioButton.Tag);
            //}
            return 0;
        }


        private void AutoData()
        {
            int count = 500;
            //while(true)
            //{

              

                //if (IsVertical)
                //{
                //    if (V_ObservableValues.Count > count)
                //    {
                //        RemoveItem();
                //    }

                //    if (V_ObservableValues.Count <= count)
                //    {
                //        AddItem();
                //    }

                //}
                //else
                //{
                //    if (ObservableValues.Count > count)
                //    {
                //        RemoveItem();
                //    }

                //    if (ObservableValues.Count <= count)
                //    {
                //        AddItem();
                //    }

                //}
               
                
            //}
          
        }


        public void AddItem()
        {
            double error_nunber = 0.05;
            //var randomValue = _random.NextInt64(234945, 235055);
            //CurrentLength = Convert.ToDouble(randomValue)/1000;
            // the new value is added to the collection // mark
            // the chart is listening, and will update and animate the change // mark
            //CurrentLength = randomValue;
         
         
            MaxLengthList.Add(CurrentLength);
            if (IsVertical)
            {
      
                if ((CurrentLength < MinVerticalLength) || MinVerticalLength==0)
                {
                   
                    MinVerticalLength = CurrentLength;
                }

            }
            else
            {
                //ObservableValues.Add(new() { Value = CurrentLength });
           
            }


            //ObservableValues.Add(new() { Value = CurrentLength });
            //SKColor color = new SKColor();
            //if(CurrentLength < 235- error_nunber)
            //{
            //    color = SKColors.DarkRed;
            //    LessThan++;
            //}
            //else if (CurrentLength >= 235- error_nunber && CurrentLength < 235+ error_nunber)
            //{
            //    color = SKColors.Green;
            //}
            //else if (CurrentLength > 235+ error_nunber)
            //{
            //    color = SKColors.Yellow;
            //    MoreThan++;
            //}
            //PieSeries.Add(new PieSeries<ObservableValue> { Values = [new ObservableValue(1)], Fill = new SolidColorPaint(color),AnimationsSpeed=new TimeSpan(0),Name= CurrentLength.ToString() });
        }


        public void RemoveItem()
        {
         

            // the last value is removed from the collection // mark
            // the chart is listening, and will update and animate the change // mark

       
            if (IsVertical)
            {
          
             
            }
            else
            {
                //if (ObservableValues.Count == 0) return;
                //ObservableValues.RemoveAt(0);
             
            }
            PieSeries.RemoveAt(0);
        }

  

        private void InitPieChart()
        {
            
            for (int i = 0;i<100;i++)
            {
             
                PieSeries.Add(new PieSeries<ObservableValue> { Values = [new ObservableValue(1)], Fill = new SolidColorPaint(SKColors.DodgerBlue),Name="1123", DataLabelsFormatter = point => point.Context.Series.Name + "：" + point.Coordinate.PrimaryValue.ToString() });
            }
          


        }

        private bool _isAllZero;    // 判断饼图中是否所有数据都是0

        /// <summary>
        /// 创建饼图
        /// </summary>
        /// <param name="titles">饼图标签</param>
        /// <param name="data">饼图数据</param>
        /// <returns></returns>
        private ISeries[] CreatePieChart(string[] titles, double[] data)
        {
            ISeries[] seriesCollection;
            _isAllZero = data.All(x => x == 0);

            // 如果所有数据不都为0
            if (!_isAllZero)
            {
                // 创建饼图数据
                List<PieSeries<double>> seriesList = new List<PieSeries<double>>();
                // 定义一个颜色数组
                var colors = new SKColor[] { SKColors.DodgerBlue, SKColors.OrangeRed, SKColors.YellowGreen };
                for (int i = 0; i < titles.Length; i++)
                {
                    if (data[i] != 0)
                    {
                        var series = new PieSeries<double>
                        {
                            // 设置扇形名称
                            Name = titles[i],
                            // 设置饼图扇形数据
                            Values = new double[] { data[i] },
                            // 设置饼图扇形填充颜色
                            Fill = new SolidColorPaint(colors[i]),
                            // 设置数据标签字体大小
                            DataLabelsSize = 15,
                            // 设置数据标签颜色
                            DataLabelsPaint = new SolidColorPaint(SKColors.White),
                            // 设置数据标签位置
                            DataLabelsPosition = LiveChartsCore.Measure.PolarLabelsPosition.Middle,
                            // 设置数据标签格式化器
                            DataLabelsFormatter = point => point.Context.Series.Name + "：" + point.Coordinate.PrimaryValue.ToString(),
                            //  DataLabelsFormatter = _ => "", // 隐藏数据标签
                        };
                        seriesList.Add(series);
                    }
                }
                seriesCollection = seriesList.ToArray();
            }
            // 如果所有数据都为0，则添加一个虚拟的系列
            else
            {
                seriesCollection = new ISeries[1];
                // 添加一个虚拟的系列，确保总有一部分被显示
                var virtualSeries = new PieSeries<double>
                {
                    Name = "无",
                    Values = new double[] { 1 },
                    Fill = new SolidColorPaint(SKColor.Parse("#55B155")),
                    // 设置数据标签字体大小
                    DataLabelsSize = 15,
                    // 设置数据标签颜色
                    DataLabelsPaint = new SolidColorPaint(SKColors.White)
                    {
                        SKFontStyle = SKFontStyle.Italic,
                    },
                    // 设置数据标签位置
                    DataLabelsPosition = LiveChartsCore.Measure.PolarLabelsPosition.Middle,
                    DataLabelsFormatter = point => point.Context.Series.Name ?? "无",
                    // 提示框文字格式
                    ToolTipLabelFormatter = _ => "",
                };
                seriesCollection[0] = virtualSeries;
            }

            return seriesCollection;
        }
        public  double GetMaxNumber(List<double?> data)
            {

                //double c_numnber = data.Max()-0.02;
                //var bb= data.Where(t=>)

                return 0;
            }


        /// <summary>
        /// 范围筛选
        /// </summary>
        /// <param name="data"></param>
        /// <param name="minValue"></param>
        /// <param name="maxValue"></param>
        /// <returns></returns>
        public static List<double> FilterByRange(List<double> data, double minValue, double maxValue)
        {
            return data.Where(x => x >= minValue && x <= maxValue).ToList();
        }

        /// <summary>
        /// 变化率筛选
        /// </summary>
        /// <param name="data"></param>
        /// <param name="maxChangeRate"></param>
        /// <returns></returns>
        public static List<PoseDetail> FilterByRateOfChange(List<PoseDetail> data, double maxChangeRate)
        {
            if (data.Count < 3) return data.ToList();
            //var avg = data.Average(t => t.Length);
            //data.ForEach(t => t.Length -= avg);

            var filteredData = new List<PoseDetail> { data[0], data[1] };

            for (int i = 2; i < data.Count; i++)
            {
                var a = Math.Abs(data[i].Length - data[i - 1].Length);
                var b = Math.Abs(data[i - 1].Length - data[i - 2].Length);
                double changeRate =a /b ;

                if (changeRate <= maxChangeRate)
                {
                    filteredData.Add(data[i]);
                }
                else
                {
                    // 可以选择用前一个值替代，或者插值 并且修改错误数值

                    filteredData.Add(filteredData.Last());
                    if (data.Count() > i + 1)
                    {
                        data[i].Length = (data[i - 1].Length + data[i + 1].Length) / 2;
                    }

                }
            }

            return filteredData;
        }


        /// <summary>
        /// 中位数
        /// </summary>
        /// <param name="data"></param>
        /// <param name="windowSize"></param>
        /// <returns></returns>
        public static List<double> MedianFilter(List<double> data, int windowSize)
        {
            var filteredData = new List<double>();

            for (int i = 0; i < data.Count; i++)
            {
                int start = Math.Max(0, i - windowSize / 2);
                int end = Math.Min(data.Count - 1, i + windowSize / 2);

                var window = data.Skip(start).Take(end - start + 1).OrderBy(x => x).ToList();
                double median = window[window.Count / 2];

                filteredData.Add(median);
            }

            return filteredData;
        }

        /// <summary>
        /// 统计方法
        /// </summary>
        /// <param name="data"></param>
        /// <param name="windowSize"></param>
        /// <param name="threshold"></param>
        /// <returns></returns>
        public static List<double> FilterByStandardDeviation(List<double> data, int windowSize, double threshold)
        {
            var filteredData = new List<double>();

            for (int i = 0; i < data.Count; i++)
            {
                int start = Math.Max(0, i - windowSize / 2);
                int end = Math.Min(data.Count - 1, i + windowSize / 2);

                var window = data.Skip(start).Take(end - start + 1).ToList();
                double mean = window.Average();
                double stdDev = Math.Sqrt(window.Sum(x => Math.Pow(x - mean, 2)) / window.Count);

                if (Math.Abs(data[i] - mean) <= threshold * stdDev)
                {
                    filteredData.Add(data[i]);
                }
            }

            return filteredData;
        }






    }
}
